package jenkins

import (
	"context"
	"fmt"
	"github.com/bndr/gojenkins"
	"server/common"
	"server/internal/model"
	"server/logger"
	"strconv"
	"strings"
	"sync"
	"time"
)

type JenkinsJobs struct {
	jobs map[string]bool
	lock sync.RWMutex
}

var (
	Jenkins *gojenkins.Jenkins
	Jctx    = context.Background()
	JenJobs = JenkinsJobs{}
)

func init() {
	JenJobs.jobs = make(map[string]bool)
}

func (jb *JenkinsJobs) Store(key string, value bool) {
	jb.lock.Lock()
	defer jb.lock.Unlock()
	jb.jobs[key] = value
}

func (jb *JenkinsJobs) Init(key string, value bool) {
	jb.GetAllJobs()
	go jb.Monitor()
}

func (jb *JenkinsJobs) GetAllJobs() {

}

func (jb *JenkinsJobs) Monitor() {

}

type JenkinsJob struct {
	Name string
	ID   int64
}

func RunJenkins() (JenkinsJob, error) {
	var job JenkinsJob
	var m map[string]string
	var name string

	id, _ := Jenkins.BuildJob(Jctx, name, m)
	build, err := Jenkins.GetBuildFromQueueID(Jctx, id)
	if err != nil {
		return job, err
	}

	job.ID, err = strconv.ParseInt(build.Raw.ID, 10, 64)
	job.Name = name

	return job, nil
}

func OneJobBuild(jenkins *gojenkins.Jenkins, jobname string) {
	jobarr := strings.Split(jobname, "/")
	newjobname := strings.Join(jobarr, "/job/") //newjobname: tomcat-test/job/open-api
	fmt.Printf("newjobname: %v\n", newjobname)
	_, err := jenkins.BuildJob(Jctx, newjobname, nil)
	if err != nil {
		panic(err)
	}
}

func AllJobBuild(jenkins *gojenkins.Jenkins, jobname string) {
	_, err := jenkins.BuildJob(Jctx, jobname, nil)
	if err != nil {
		panic(err)
	}
}

func GetAllJobs() map[string]bool {
	jobs := make(map[string]bool)
	return jobs
}

func (job *JenkinsJob) BindJenkins() {
	for {
		status, _ := job.JobStatus()
		if status != common.RUNNING {
			break
		}
		time.Sleep(15 * time.Second)
	}
}

func (job *JenkinsJob) JobStatus() (string, error) {
	jobs, err := Jenkins.GetBuild(Jctx, job.Name, job.ID)
	if err != nil {
		return "", err
	}
	status := jobs.Raw.Result
	switch status {
	case "SUCCESS":
		return common.SUCCESS, nil
	case "FAILURE":
		return common.FAIL, nil
	case "ABORTED":
		return common.STOPPED, nil
	default:
		return common.RUNNING, nil
	}
}

func (job *JenkinsJob) Stop() bool {
	build, err := Jenkins.GetBuild(Jctx, job.Name, job.ID)
	if err != nil {
		logger.Error(err.Error())
	}
	status, err := build.Stop(Jctx)
	if err != nil {
		logger.Error(err.Error())
	}
	return status
}

var lock = sync.Mutex{}

func Run(param map[string]string) (string, string, error) {
	lock.Lock()
	defer lock.Unlock()

	jobs, err := model.QueryIdleJob(param["product"])
	if err != nil {
		logger.Error(err.Error())
		return "", "", err
	}

	var jenken_job_name string
	var jenken_job_id int64

	for _, job := range jobs {
		jenken_job_name = job.Name
		jenken_job_id, _ = Jenkins.BuildJob(Jctx, jenken_job_name, param)
		if jenken_job_id != 0 {
			logger.Error(fmt.Sprintf("【任务】%s,执行成功，Jid:%d,JName:%s", param["TaskName"], jenken_job_id, jenken_job_name))
			break
		}
	}
	if jenken_job_id == 0 {
		logger.Error(fmt.Sprintf("【任务】%s,执行失败，无执行机可用", param["TaskName"]))
		return "", "", err
	}

	jenkins_job := model.Jenkins{Name: jenken_job_name, Status: true}
	_ = jenkins_job.Update()

	//根据Jenkins ID获取运行情况
	build, err := Jenkins.GetBuildFromQueueID(Jctx, jenken_job_id)
	if err != nil {
		logger.Error(err.Error())
	}
	return build.Raw.ID, jenken_job_name, nil
}
